package main;

import java.awt.DisplayMode;
import java.awt.Graphics;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.MemoryImageSource;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;

import javax.swing.JFrame;

public class PGMTest {

	// quick testing class - just to point the direction...

	public static void main(String[] args) {

		int picWidth;
		int picHeight;
		int picColors;

		byte[][] data2D = null; // raw picdata as 2dim array

		String filePath = "C:\\Users\\Marcos\\Desktop\\6.pgm";

		try {

			// prepare stream tokenizer and buffered reader
			// streamtokenizer is the easy way to read in tokens (="words")
			// and is used just to read in header information from the pictures

			FileInputStream fileInputStream = new FileInputStream(filePath);
			BufferedReader bufferedReader = new BufferedReader(
					new InputStreamReader(fileInputStream));
			StreamTokenizer streamTokenizer = new StreamTokenizer(
					bufferedReader);

			// comments can only be made with # within the file ('//' and '/*
			// */' are not allowed!)
			streamTokenizer.commentChar('#');
			streamTokenizer.eolIsSignificant(false);
			streamTokenizer.slashStarComments(false);
			streamTokenizer.slashSlashComments(false);

			try {

				// //////////////////
				// READING HEADER //
				// //////////////////

				// the header information is the beginning of your file (open it
				// with a text editor like notepad)
				// which contains so called meta information (information which
				// do not actually belong to the picture)
				// like file format, number of colors, height and width of your
				// pics.
				// comments can be written into the header with '#'.
				// the file you sent me looked like this when i opened it:
				//
				// P5
				// # Created by Imlib
				// 512 512
				// 255

				// checking if it is a pgm file (pgm files start with "p5")
				int type = streamTokenizer.nextToken(); // reading next "word"

				// if first token is a number (TT_NUMBER) then quit else get the
				// string value and check if it's "P5"
				// it has to be P5, else it's not a PGM file then quit
				if ((type == StreamTokenizer.TT_NUMBER)
						|| (streamTokenizer.sval.compareTo("P5") != 0)) {
					System.err.println("ERROR: " + filePath
							+ " is not a PGM-file!");
					System.exit(-1);
				}

				// reading the file header which contains information about the
				// picture (x/y size and color)

				streamTokenizer.nextToken(); // reading next "word"
				picWidth = (int) streamTokenizer.nval; // get width

				streamTokenizer.nextToken(); // reading next "word"
				picHeight = (int) streamTokenizer.nval; // get height

				streamTokenizer.nextToken(); // reading next "word"
				picColors = (int) streamTokenizer.nval + 1; // max. color value
															// + 1

				// ////////////////////////////////////////////
				// READING BINARY DATA - THE ACTUAL PICTURE //
				// ////////////////////////////////////////////

				// because the height and width is known since we read the
				// header information
				// we can now build up an byte array which will contain the raw
				// picture information
				// by running through a row loop which again contains a column
				// loop.
				// the data read

				// from now on we have binary data
				data2D = new byte[picWidth][picHeight];

				// reading binary data and put it into the byte array data2D.
				for (int row = 0; row < picHeight; row++) {
					for (int col = 0; col < picWidth; col++) {
						data2D[col][row] = (byte) (bufferedReader.read());
					}
				}

				fileInputStream.close();
			}

			catch (IOException e) {
				System.err.println("Error while reading file " + filePath);
				System.exit(1);
			}
		}

		catch (FileNotFoundException e) {
			System.err.println("Error: File " + filePath + " not found!");
			System.exit(1);
		}

		// //////////////////////
		// DISPLAYING PICTURE //
		// //////////////////////
		//
		// after all reading is done, present the picture in a window
		// i have done this very quick and dirty and it doesn't look exactly
		// like the picture you sent me, but you get the idea ...
		// actually i don't know if the errors already occure during the file
		// reading - maybe the values are cut off?
		// or maybe you just need to find a way to display greyscale pics - i am
		// not so familiar with that topic.
		// was late at night - as usual...

		drawIt(data2D);
	}

	public static void drawIt(byte[][] data2D) {

		JFrame defaultFrame;
		GraphicsEnvironment graphicsEnvironment;
		GraphicsDevice defaultScreenDevice;
		int screenWidth;
		int screenHeight;
		int size;
		Image offscreen;
		MemoryImageSource memImageSource;
		int[] pixels;
		Graphics graphic;

		graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
		defaultScreenDevice = graphicsEnvironment.getDefaultScreenDevice();
		defaultFrame = new JFrame(defaultScreenDevice.getDefaultConfiguration());

		defaultFrame.setUndecorated(false);
		defaultFrame.setIgnoreRepaint(true);

		defaultScreenDevice.setFullScreenWindow(defaultFrame);

		DisplayMode[] affichages = defaultScreenDevice.getDisplayModes();

		int i;
		for (i = 0; i < affichages.length; i++) {
			if ((affichages[i].getWidth() == 1024)
					&& (affichages[i].getHeight() == 768)
					&& (affichages[i].getBitDepth() == 32))
				defaultScreenDevice.setDisplayMode(affichages[i]);
		}
		screenWidth = defaultFrame.getWidth();
		screenHeight = defaultFrame.getHeight();
		size = screenWidth * screenHeight;
		pixels = new int[size];

		memImageSource = new MemoryImageSource(screenWidth, screenHeight,
				pixels, 0, screenWidth);
		offscreen = Toolkit.getDefaultToolkit().createImage(memImageSource);
		graphic = defaultFrame.getGraphics();

		defaultFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		defaultFrame.setVisible(true);

		for (int row = 0; row < data2D.length; row++) {
			for (int col = 0; col < data2D[0].length; col++) {
				pixels[col * screenWidth + row] = (data2D[row][col] << 24) ^ 0xFF000000;
			}
		}
		memImageSource.newPixels();
		graphic.drawImage(offscreen, 0, 0, null);
	}
}